home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 July / Macworld (1999-07).dmg / Shareware World / Info / For Developers / Mops 3.4.sea / Mops source / Module source / windowmod.txt < prev    next >
Text File  |  1999-02-05  |  11KB  |  437 lines

  1. \ Window class.
  2.  
  3. \  May 91 mrh    Added NonScrollWind.
  4. \    Default grow and drag limits set at grow and drag time.
  5. \    Also fixed a number of long-standing bugs in draw:, enable:, disable:
  6. \    etc.  New: deactivates current window.  Added PenIntoWind:.
  7.  
  8. \    Nov95 JRF    Option to not outline unused scroll bars
  9.  
  10.  
  11. \        ===================================
  12.  
  13. \ WINDOW is the basic window class, with no controls.
  14. \  For windows with controls, use Window+.
  15.  
  16. \        ===================================
  17.  
  18. :class    WINDOW  super{ grafPort }
  19. 68k_record
  20. {    $ 20    bytes    wind1            \ unmapped
  21.             handle    CTLLIST            \ 1st ctl
  22.     $ 0C    bytes    wind2            \ unmapped
  23.  
  24.             rect    CONTRECT        \ true content
  25.             rect    GROWRECT        \ grow size rectangle
  26.             rect    DRAGRECT        \ drag limits rect
  27.  
  28.             bool    GROWFLG            \ true if growable
  29.             bool    DRAGFLG            \ true if draggable
  30.             bool    ALIVE            \ true if space exists
  31.             bool    SCROLLFLG        \ true if scrollable
  32.             bool    COLOR?            \ true if this is a color window
  33.  
  34.             x-addr    IDLE            \ idle handler
  35.             x-addr    DEACT            \ deactivate event handler
  36.  
  37.             x-addr    CONTENT            \ content handler
  38.             x-addr    DRAW            \ draw handler
  39.             x-addr    ENACT            \ activate event handler
  40.             x-addr    CLOSE            \ close handler
  41.  
  42.             int        RESID            \ resource id
  43.             
  44.             bool    ClipGrowLeft    \ Nov95 JRF Option to not outline unused HScroll
  45.             bool    ClipGrowTop        \ ditto unused VScroll -- DrawGrowIcon normally
  46.  
  47.             rect    thefprect        \ 17Dec98 DBH - we now save fpRect here over
  48.                                     \  a DRAW:, rather than in the stack which
  49.                                     \  makes the Mops stack display look strange.
  50. }
  51. public
  52.     ptr        ^view_in_focus            \ points to view which gets keys etc.
  53.             
  54. private
  55.  
  56. :m SETLIMITS:    \ Sets GrowRect and DragRect to reasonable default values
  57.                 \ according to the current screen size at the time the grow
  58.                 \ or drag is done.  Programs such as SteppingOut can change
  59.                 \ the screen size while a window is open!
  60.  
  61.     screenbits  put: dragRect
  62.     40 40 getBot: dragRect  put: growRect
  63.     4 4 inset: dragRect  ;m
  64.  
  65. :m ?SETFPRECT:    \ Sets fPrect if scrollFlg is true.  fPrect is needed by
  66.                 \ the nucleus for scrolling fWind, before proper window
  67.                 \ handling is loaded.  But it can be used for scrolling
  68.                 \ text in any other window as well, if scrolling is enabled
  69.                 \ for that window.
  70.  
  71.     get: scrollFlg IF  get: contRect  put: fPrect  THEN  ;m
  72.  
  73. :m ?DISABLE_ACTW:    \ Deactivates the currently active window before a New:
  74.                     \ or GetNew: call, if there is a currently active Mops 
  75.                     \ window.
  76.     ?disable_actw  0 -> actW  ;m
  77.  
  78. :m InitNewWindow:
  79.     setContRect: [self]
  80.     set: self  initfont  true  put: alive
  81.     cls  ;m
  82.  
  83. :m PenIntoWind:    \ Moves the GrafPort pen back into the window area if
  84.                 \ necessary, after the window has been resized.
  85.                 \ Actually at the moment we only worry about the vertical
  86.                 \ direction.
  87.     @xy bottom min  gotoxy  ;m
  88.  
  89. public
  90.  
  91. \ Grow icon methods:
  92.  
  93. :m SETCLIPGROWLEFT:    put: clipgrowleft ;m    \ Nov95 JRF
  94. :m SETCLIPGROWTOP:    put: clipgrowtop ;m        \ Nov95 JRF
  95.  
  96. :m DRAWGROW:  { \ l t r b -- }                \ Nov95 JRF rev.
  97.     get: growFlg  0EXIT
  98.     get: clipgrowleft get: clipgrowtop OR
  99.     NIF    noClip
  100.         @xy   ^base  DrawGrowIcon
  101.         gotoxy
  102.         EXIT
  103.     THEN
  104.     getRect: self  -> b -> r -> t -> l
  105.     get: clipgrowleft IF r 15 - ELSE 0 THEN
  106.     get: clipgrowtop  IF b 15 - ELSE 0 THEN
  107.     r b put: tempRect clip: tempRect
  108.     @xy     ^base  DrawGrowIcon
  109.     gotoxy  noClip  ;m
  110.  
  111.  
  112. :m ERASEGROW:  { \ l t r b -- }
  113.     get: growFlg  0EXIT
  114.     noClip
  115.     getRect: self  -> b -> r -> t -> l
  116.     r 13 -  b 13 -  r  b  put: tempRect
  117.     clear: tempRect  ;m
  118.  
  119.  
  120.  
  121. :m SETCONTRECT:    \ Sets ContRect to the viewing area.  Must be public since 
  122.                 \ we late-bind to it, and it gets called from ObjInit anyway.
  123.  
  124.     get: portRect  get: growFlg
  125.     IF  swap 15 -  swap  15 -  THEN   put: contRect
  126.     ?setfPrect: self  ;m
  127.  
  128. :m CLOSE:
  129.     get: alive  0EXIT
  130.     ^base  CloseWindow
  131.     ^base actW = IF  0 -> actW  THEN    \ If this was the active window, it
  132.                                         \  isn't any more
  133.     clear: alive   exec: close  ;m
  134.  
  135. :m RELEASE:    close: [self]  ;m    \ Standard destructor - same as close.
  136.  
  137. :m SET:        \ Makes this wind the current GrafPort.  It used
  138.             \ to call setContRect: but there's really no need.
  139.     set: super
  140.     ?setfPrect: self  ;m
  141.  
  142. :m UPDATE:    \ Generates an update event for the window with its
  143.             \  entire port rectangle as the update region.
  144.     pushPort  set: self
  145.     getRect: self  put: tempRect  update: tempRect
  146.     popPort  ;m
  147.  
  148.  
  149. :m NEW: { bndsRect tAddr tLen procID vis goAway \ s255 -- }
  150.  
  151.   \ Defines a new window on the heap with the specified features.
  152.   \ Not resource based.
  153.  
  154.     get: alive  ?EXIT                \ Out if already alive
  155.     bndsRect ->: contRect            \ save rect locally
  156.     ?disable_actW: self
  157.     tAddr tLen  str255  -> s255
  158.     ^base  addr: contRect  s255
  159.     vis 1 and
  160.     procID
  161.     inFront  goAway 1 and
  162.     0                                \ default is initially in front
  163.     get: color?
  164.     IF  NewCWindow  ELSE  NewWindow  THEN  drop
  165.     initNewWindow: self  ;m
  166.  
  167.  
  168. :m GETNEW:        \ ( resid -- )   Resource based new window.
  169.  
  170.     get: alive  IF  drop  EXIT  THEN    \ Out if already alive
  171.     ?disable_actW: self
  172.     dup  put: resid  ^base  inFront
  173.     get: color?
  174.     IF    GetNewCWindow  ELSE  GetNewWindow  THEN  drop
  175.     initNewWindow: self  ;m
  176.  
  177.  
  178. :m GETVSRECT:    \ ( l t r b -- l' t' r' b' )
  179.                 \ Returns the default vert. scroll bar rect.
  180.     get: portRect  >vrect  ;m
  181.  
  182. :m GETHSRECT:    \ ( l t r b -- l' t' r' b' )
  183.                 \ Returns the default horiz. scroll bar rect.
  184.     get: portRect  >hrect  ;m
  185.  
  186.  
  187. (*    The DRAW: method is called, late-bound, whenever a window is updated.
  188.     The implementation must begin with a BeginUpdate call and end with an
  189.     EndUpdate call.  We use the CallFirst/CallLast mechanism to ensure this,
  190.     and also to draw the grow icon if this is a growable window.  This means
  191.     that any redefinition of DRAW: in a subclass should not call DRAW: super,
  192.     since this would lead to BeginUpdate and EndUpdate being called more than
  193.     once.  So we define another method (DRAW): to do the actual work for DRAW:,
  194.     and subclasses which need their own versions of DRAW: may call (DRAW):
  195.     freely.
  196. *)
  197.  
  198. private
  199.  
  200. :m (DRAW):        \ Does the main work for DRAW:.
  201.     savePort  @xy  set: self    \ Save port and pen posn, reset to this 
  202.                                 \  window
  203.     exec: draw                    \ Call user draw routine
  204.     restPort gotoxy                \ Restore pen posn, restore original port
  205. ;m
  206.  
  207. :m SETUP_DRAW:
  208.     get: fPrect put: thefprect        \ 17Dec98 DBH - Save fPrect as it might get changed
  209.     ^base  BeginUpdate
  210. ;m
  211.  
  212. :m WINDUP_DRAW:
  213.     drawGrow: self
  214.     ^base  EndUpdate
  215.     get: thefprect put: fPrect        \ 17Dec98 DBH - Restore fPrect
  216. ;m
  217.  
  218. callFirst    setup_draw:
  219. callLast    windup_draw:
  220.  
  221. public
  222.  
  223. :m DRAW:    (draw): self  ;m
  224.  
  225. :m SELECT:        \ Makes this the front window.
  226.     ^base  SelectWindow
  227.     ?setfPrect: self  ;m
  228.  
  229.  
  230. (*    The idle: method is called for the frontmost window, whenever a null
  231.     event occurs.  NULL-EVT is the normal word which sends idle:.  In
  232.     subclasses we redefine this method to do things like calling TEidle,
  233.     which have to be done periodically.  The Idle handler is also called,
  234.     which allows a window-specific action to be taken.  In the class Window
  235.     itself, this is all we do.
  236. *)
  237.  
  238. :m IDLE:        exec: idle  ;m
  239.  
  240. :m SETIDLE:        put: idle  ;m
  241.  
  242.  
  243. :m ENABLE:        \ Handles an activate event.
  244.     set: self
  245.     drawGrow: self
  246.     exec: enact  ;m
  247.  
  248. :m DISABLE:        \ Handles a deactivate event.
  249.     eraseGrow: self
  250.     exec: deact  ;m
  251.  
  252.  
  253. :m ACTIONS:        \ ( close enact draw cont 4 -- )
  254.                 \ Sets up window event handler words.  We require
  255.                 \ an xt count as this is normal for actions: methods.
  256.     4 ?#xts
  257.     put: content  put: draw  put: enact  put: close  ;m
  258.  
  259.  
  260. :m SETACT:    \ ( enact deact -- )  Sets just the activate/deactivate
  261.             \ event handlers
  262.     put: deact  put: enact  ;m
  263.  
  264.  
  265. :m SETDRAW:        \ ( xt -- )  Sets the draw handler
  266.     put: draw  ;m
  267.  
  268.  
  269. :m SETCOLOR:    \ ( b -- )  Sets the color? flag.
  270.     put: color?  ;m
  271.  
  272.  
  273. :m ACTIVE:    \ ( -- b )  Is this window active ?
  274.     FrontWindow  ^base =  ;m
  275.  
  276.  
  277. :m ALIVE:    \ ( -- b )  Is this window alive?
  278.     get: alive  ;m
  279.  
  280.  
  281. :m DRAG:    \ Handles a drag region click
  282.     setLimits: self                    \ Omit in subclasses which need
  283.                                     \  custom drag limits
  284.     get: dragFlg  0EXIT
  285.     ^base  whrFEv  addr: dragRect
  286.     DragWindow  ;m
  287.  
  288. private
  289.  
  290. \ Some housekeeping routines for Size: and Zoom:
  291.  
  292. :m ClrOldBars:
  293.     getVSrect: self 16 +  put: tempRect
  294.     clear: tempRect  update: tempRect    \ Including the grow box
  295.     getHSrect: self  put: tempRect
  296.     clear: tempRect  update: temprect  ;m
  297.  
  298. :m FixNewBars:
  299.     ClrOldBars: self                    \ Yes, the code's the same so far!!
  300.     addr: portRect  ClipRect
  301.     setContRect: [self]
  302.     penIntoWind: self  ;m
  303.  
  304. public
  305.  
  306. :m SIZE:  { wid ht -- }    \ Resizes window and accumulates update regions.
  307.     ^base  wid ht  true
  308.     ClrOldBars: self
  309.     SizeWindow
  310.     FixNewBars: self  ;m
  311.  
  312. :m SETSIZE:    size: self  ;m    \ For naming consistency with Rects and 
  313.                             \  Views.
  314.  
  315.  
  316. :m MOVE: { x y -- }        \ Moves the window.
  317.     ^base x y
  318.     0            \ don't bring to front - leave where it is
  319.     MoveWindow  ;m
  320.  
  321.  
  322. :m CENTER:  { \ sw sh pw ph -- }
  323.         \ Centers the window on the screen.
  324.         \ Yeah, I know, here in Oz we spell this "centre", but we Ozzies
  325.         \ are more flexible than the Yanks, so we'll magnanimously do it
  326.         \ their way, not ours.
  327.         
  328.     screenbits  -> sh  -> sw  2drop
  329.     size: portRect  -> ph  -> pw
  330.     sw pw - 2/  sh ph - 2/  move: self  ;m
  331.  
  332.  
  333. :m ZOOM:  { part -- }
  334.     ^base  whrFEv part TrackBox
  335.     IF    getRect: self  put: tempRect  tempRect  EraseRect
  336.         ^base  part 0  ZoomWindow
  337.         FixNewBars: self
  338.     THEN  ;m
  339.  
  340.  
  341. :m GROW:        \ Handles a mouse-down in the grow box.
  342.     get: growFlg
  343.     IF    setLimits: self                    \ Omit in subclasses which need
  344.                                         \  custom grow limits
  345.         ^base  whrFEv  addr: growrect
  346.         GrowWindow            \ returns a packed point, or 0
  347.         ?dup
  348.         IF    unpack ( wid ht )  size: self  ( draw: self )
  349.             penIntoWind: self
  350.         THEN
  351.     ELSE
  352.         ^base  SelectWindow
  353.     THEN
  354.     update: self  ;m
  355.  
  356.  
  357. :m CONTENT:        \ Handles a content click.
  358.     active: self
  359.     IF        exec: content
  360.     ELSE    select: self
  361.     THEN  ;m
  362.  
  363.  
  364. :m TITLE:    \ ( addr len -- )  Sets the title of the window.
  365.     str255  ^base  swap  SetWTitle  ;m
  366.  
  367. :m NAME:  ( addr len -- )    title: self  ;m        \ An alias for TITLE:.
  368.  
  369.  
  370. :m GETNAME:    \ ( -- addr len )  Returns name of window.
  371.     ^base  buf255  GetWTitle
  372.     buf255 count  ;m
  373.  
  374.  
  375. :m MAXX:    \ ( -- x )  Returns the x coordinate value corresponding to
  376.             \  the window being moved to the right of the screen.
  377.     screenbits drop nip nip
  378.     size: portRect  drop  -  ;m
  379.  
  380.  
  381. :m MAXY:    \ ( -- y )
  382.     screenbits nip nip nip
  383.     size: portRect  nip  -  ;m
  384.  
  385. \            =================
  386.  
  387. :m KEY:        \ ( c -- )  May be used in subclasses to do something with
  388.             \  typed keys.  Here, we just drop it.
  389.     drop  ;m
  390.  
  391.  
  392. :m SHOW:    ^base  ShowWindow  ;m
  393.  
  394. :m HIDE:    ^base  HideWindow  ;m
  395.  
  396.  
  397. :m SETGROW:    \ ( l t r b  T  |  F -- )  Sets grow limits, if boolean is true.
  398.  
  399.     \ Note: in class Window itself, we IGNORE these grow limits and
  400.     \  use a default value based on the size of the screen at the time
  401.     \  the grow is actually done.
  402.  
  403.     dup  put: growFlg
  404.     IF  put: growrect  THEN  ;m
  405.  
  406. :m SETDRAG:    \ ( l t r b  T  |  F -- )  Sets drag limits.
  407.  
  408.     \ Note: in class Window itself, we IGNORE these drag limits and
  409.     \  use a default value based on the size of the screen at the time
  410.     \  the drag is actually done.
  411.  
  412.     dup  put: dragFlg
  413.     IF  put: dragRect  THEN  ;m
  414.  
  415. :m SETSCROLL:    \ ( b -- )
  416.     put: scrollFlg  ;m
  417.  
  418.  
  419. :m CLASSINIT:
  420.     xts{ null null null null }  actions: self
  421.     ['] null  dup  put: idle  put: deact
  422.     true  put: scrollFlg  true  put: dragFlg  ;m
  423.  
  424.  
  425. :m MARKALIVE:    \ A special method really intended just to allow us to
  426.                 \ mark fWind alive on startup.
  427.     true  put: alive   ;m
  428.  
  429.  
  430. :m TEST:        \ Fires up a test window.
  431.     100 100 300 200 put: tempRect
  432.     screenbits true setGrow: self
  433.     tempRect  " Test"  docWind  true true  new: self  ;m
  434.  
  435. ;class
  436.  
  437.